#include <iostream>
#include <string>

// 结构体，用于展示指定初始化器
struct Point {
    int x = 0;
    int y = 0;
    int z = 0;
};

// 带有嵌套结构的结构体
struct Rectangle {
    Point top_left;
    Point bottom_right;
    std::string name;
    bool filled = false;
    int line_width = 1;
    unsigned int color = 0x000000;  // 默认黑色
};

// 含有多种类型的复杂结构体
struct Configuration {
    struct {
        int width = 800;
        int height = 600;
        bool fullscreen = false;
        std::string title = "Default Window";
    } window;
    
    struct {
        float master = 1.0f;
        float music = 0.8f;
        float effects = 0.5f;
        bool muted = false;
    } audio;
    
    struct {
        int difficulty = 1;  // 1-简单, 2-中等, 3-困难
        bool tutorials = true;
        std::string language = "en";
        int save_slot = 0;
    } gameplay;
};

// 打印函数
void print_point(const Point& p) {
    std::cout << "  Point{x=" << p.x << ", y=" << p.y << ", z=" << p.z << "}\n";
}

void print_rectangle(const Rectangle& r) {
    std::cout << "  Rectangle{" << r.name << "} {\n";
    std::cout << "    top_left: (" << r.top_left.x << ", " << r.top_left.y << ")\n";
    std::cout << "    bottom_right: (" << r.bottom_right.x << ", " << r.bottom_right.y << ")\n";
    std::cout << "    filled: " << std::boolalpha << r.filled << "\n";
    std::cout << "    line_width: " << r.line_width << "\n";
    std::cout << "    color: 0x" << std::hex << r.color << std::dec << "\n";
    std::cout << "  }\n";
}

void print_configuration(const Configuration& config) {
    std::cout << "  Configuration {\n";
    std::cout << "    window: {\n";
    std::cout << "      width: " << config.window.width << "\n";
    std::cout << "      height: " << config.window.height << "\n";
    std::cout << "      fullscreen: " << std::boolalpha << config.window.fullscreen << "\n";
    std::cout << "      title: " << config.window.title << "\n";
    std::cout << "    }\n";
    std::cout << "    audio: {\n";
    std::cout << "      master: " << config.audio.master << "\n";
    std::cout << "      music: " << config.audio.music << "\n";
    std::cout << "      effects: " << config.audio.effects << "\n";
    std::cout << "      muted: " << config.audio.muted << "\n";
    std::cout << "    }\n";
    std::cout << "    gameplay: {\n";
    std::cout << "      difficulty: " << config.gameplay.difficulty << "\n";
    std::cout << "      tutorials: " << config.gameplay.tutorials << "\n";
    std::cout << "      language: " << config.gameplay.language << "\n";
    std::cout << "      save_slot: " << config.gameplay.save_slot << "\n";
    std::cout << "    }\n";
    std::cout << "  }\n";
}

void demonstrate_designated_initializers() {
    std::cout << "  C++20 指定初始化器(Designated Initializers)演示:\n\n";
    std::cout << "  注意: 由于编译器可能不完全支持C++20的指定初始化器，\n";
    std::cout << "  以下演示的语法是C++20标准的语法，但使用传统初始化方式实现。\n\n";
    
    // 1. 基本用法
    std::cout << "  基本用法:\n";
    
    // C++17及之前的初始化方式
    Point p1{10, 20, 30};  // 按字段顺序初始化
    std::cout << "  C++17按顺序初始化: ";
    print_point(p1);
    
    // C++20指定初始化器 - 语法展示
    std::cout << "  C++20指定初始化器语法:\n";
    std::cout << "  Point p2{.x = 1, .y = 2, .z = 3};\n";
    
    // 实际使用传统方式
    Point p2{1, 2, 3};
    std::cout << "  实际效果: ";
    print_point(p2);
    
    // 2. 只初始化部分字段
    std::cout << "\n  部分字段初始化:\n";
    
    // C++20语法展示 
    std::cout << "  C++20语法: Point p3{.x = 100, .z = 300};\n";
    
    // 实际使用传统方式，但保留默认值
    Point p3;
    p3.x = 100;
    p3.z = 300;
    std::cout << "  只初始化x和z: ";
    print_point(p3);
    
    // 3. 初始化顺序必须匹配声明顺序
    std::cout << "\n  初始化顺序规则:\n";
    
    // C++20语法展示
    std::cout << "  正确顺序(C++20): Point p4{.x = 5, .y = 6, .z = 7};\n";
    std::cout << "  错误顺序(C++20): Point p_error{.y = 10, .x = 5};  // 编译错误\n";
    
    // 实际使用传统方式
    Point p4{5, 6, 7};
    std::cout << "  实际效果: ";
    print_point(p4);
    
    std::cout << "  注意: 指定初始化器必须按照字段声明的顺序\n";
    
    // 4. 嵌套结构的初始化
    std::cout << "\n  嵌套结构的初始化:\n";
    
    // 使用传统的方式
    Rectangle r1{
        {10, 20}, // top_left
        {30, 40}, // bottom_right
        "矩形1",   // name
        true,     // filled
        2,        // line_width
        0xFF0000  // color (红色)
    };
    std::cout << "  传统初始化方式:\n";
    print_rectangle(r1);
    
    // C++20指定初始化器语法展示
    std::cout << "  C++20指定初始化器语法:\n";
    std::cout << "  Rectangle r2{\n";
    std::cout << "    .top_left = {.x = 15, .y = 25},\n";
    std::cout << "    .bottom_right = {.x = 35, .y = 45},\n";
    std::cout << "    .name = \"矩形2\",\n";
    std::cout << "    .filled = true,\n";
    std::cout << "    .line_width = 3,\n";
    std::cout << "    .color = 0x00FF00\n";
    std::cout << "  };\n";
    
    // 使用传统方式实现
    Rectangle r2;
    r2.top_left.x = 15;
    r2.top_left.y = 25;
    r2.bottom_right.x = 35;
    r2.bottom_right.y = 45;
    r2.name = "矩形2";
    r2.filled = true;
    r2.line_width = 3;
    r2.color = 0x00FF00;
    
    std::cout << "  实际效果:\n";
    print_rectangle(r2);
    
    // 5. 部分嵌套初始化，部分使用默认值
    std::cout << "\n  混合使用默认值和指定值:\n";
    
    // C++20语法展示
    std::cout << "  C++20语法:\n";
    std::cout << "  Rectangle r3{\n";
    std::cout << "    .top_left = {.x = 5},\n";
    std::cout << "    .bottom_right = {.x = 15, .y = 25},\n";
    std::cout << "    .name = \"矩形3\"\n";
    std::cout << "  };\n";
    
    // 使用传统方式实现
    Rectangle r3;
    r3.top_left.x = 5;
    r3.bottom_right.x = 15;
    r3.bottom_right.y = 25;
    r3.name = "矩形3";
    
    std::cout << "  实际效果:\n";
    print_rectangle(r3);
    
    // 6. 复杂结构的部分初始化
    std::cout << "\n  复杂结构的部分初始化:\n";
    
    // C++20语法展示
    std::cout << "  C++20语法:\n";
    std::cout << "  Configuration config{\n";
    std::cout << "    .window = {\n";
    std::cout << "      .width = 1280,\n";
    std::cout << "      .height = 720,\n";
    std::cout << "      .title = \"我的游戏窗口\"\n";
    std::cout << "    },\n";
    std::cout << "    .audio = {\n";
    std::cout << "      .music = 0.6f,\n";
    std::cout << "      .muted = true\n";
    std::cout << "    },\n";
    std::cout << "    .gameplay = {\n";
    std::cout << "      .difficulty = 3,\n";
    std::cout << "      .language = \"zh-CN\"\n";
    std::cout << "    }\n";
    std::cout << "  };\n";
    
    // 使用传统方式实现
    Configuration config;
    config.window.width = 1280;
    config.window.height = 720;
    config.window.title = "我的游戏窗口";
    config.audio.music = 0.6f;
    config.audio.muted = true;
    config.gameplay.difficulty = 3;
    config.gameplay.language = "zh-CN";
    
    std::cout << "  实际效果:\n";
    print_configuration(config);
    
    // 7. 指定初始化器的优势
    std::cout << "\n  指定初始化器的优势:\n";
    std::cout << "  - 清晰表达每个值对应的字段\n";
    std::cout << "  - 不需要记住字段顺序\n";
    std::cout << "  - 当结构体更新时，初始化代码更稳定\n";
    std::cout << "  - 可以跳过默认值字段，提高代码可读性\n";
    std::cout << "  - 与C语言中的指定初始化器兼容\n";
    
    // 8. 限制
    std::cout << "\n  指定初始化器的限制:\n";
    std::cout << "  - 必须按照字段声明的顺序\n";
    std::cout << "  - 不能混合使用指定初始化器和位置初始化器\n";
    std::cout << "  - 不能初始化私有或保护成员\n";
    std::cout << "  - 不能用于数组或std::vector等容器\n";
    std::cout << "  - 不能用于非聚合类 (有用户定义构造函数的类)\n";
} 